﻿//-----------------------------------------------------------------------
// 
//  This code is copied (hopefully verbatim) from this blog article:
// http://blogs.msdn.com/mshneer/archive/2007/09/05/deploying-your-vsto-add-in-to-all-users-part-ii.aspx
//
// Where different, it mirrors the (later published) MSDN article here:
// http://msdn.microsoft.com/en-us/library/cc136646.aspx
// 
// THIS CODE AND INFORMATION ARE PROVIDED AS IS WITHOUT WARRANTY OF ANY
// KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
// PARTICULAR PURPOSE.
//-----------------------------------------------------------------------

using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Win32;

namespace CustomActions
{
    public class RegisterOffice2007AddIn
    {
        #region private methods

        private const string userSettingsLocation = @"Software\Microsoft\Office\12.0\User Settings";

        public void IncrementCounter(RegistryKey instructionKey)
        {
            int count = 1;
            object value = instructionKey.GetValue("Count");

            if (value != null)
            {
                if ((int)value != Int32.MaxValue)
                    count = (int)value + 1;
            }

            instructionKey.SetValue("Count", count);
        }

        private string GetApplicationPath(string applicationName)
        {
            switch (applicationName.ToLower())
            {
                case "excel":
                    return @"Software\Microsoft\Office\Excel\Addins\";
                case "infopath":
                    return @"Software\Microsoft\Office\InfoPath\Addins\";
                case "outlook":
                    return @"Software\Microsoft\Office\Outlook\Addins\";
                case "powerpoint":
                    return @"Software\Microsoft\Office\PowerPoint\Addins\";
                case "word":
                    return @"Software\Microsoft\Office\Word\Addins\";
                case "visio":
                    return @"Software\Microsoft\Visio\Addins\";
                case "project":
                    return @"Software\Microsoft\Office\MS Project\Addins\";
                default:
                    throw new Exception(applicationName + " is not a supported application", null);
            }
        }

        #endregion

        #region Public Methods

        public void RegisterAddIn(string addInName)
        {
            RegistryKey userSettingsKey = null;
            RegistryKey instructionKey = null;

            try
            {
                // Get handle to the parent Registry key
                userSettingsKey = Registry.LocalMachine.OpenSubKey(userSettingsLocation, true);

                if (userSettingsKey == null)
                {
                    throw new Exception("Internal error: Office User Settings key does not exist", null);
                }

                // Get handle to the add-in's Registry key
                instructionKey = userSettingsKey.OpenSubKey(addInName, true);

                if (instructionKey == null)
                {
                    instructionKey = userSettingsKey.CreateSubKey(addInName);
                }
                else
                {
                    // Remove the Delete instruction
                    try
                    {
                        instructionKey.DeleteSubKeyTree("DELETE");
                    }
                    catch (ArgumentException) { } // Delete instruction did not exist but that is ok.
                }

                // Increase the Count value
                IncrementCounter(instructionKey);
            }
            finally
            {
                if (instructionKey != null)
                    instructionKey.Close();

                if (userSettingsKey != null)
                    userSettingsKey.Close();
            }
        }

        public void UnRegisterAddIn(string applicationName, string addInName)

        {
            RegistryKey userSettingsKey = null;
            RegistryKey instructionKey = null;
            RegistryKey deleteKey = null;

            try
            {
                userSettingsKey = Registry.LocalMachine.OpenSubKey(userSettingsLocation, true);

                if (userSettingsKey == null)
                {
                    throw new Exception("Internal error: Office User Settings key does not exist", null);
                }

                instructionKey = userSettingsKey.OpenSubKey(addInName, true);

                if (instructionKey == null)
                {
                    instructionKey = userSettingsKey.CreateSubKey(addInName);
                }
                else
                {
                    // Make sure there is no Create instruction
                    try
                    {
                        instructionKey.DeleteSubKeyTree("CREATE");
                    }
                    catch (ArgumentException) { } // Create instruction did not exist but that is ok.
                }

                // Save the Delete instruction
                string instructionString =
                                @"DELETE\" +
                                GetApplicationPath(applicationName) +
                                @"\" +
                                addInName;

                deleteKey = instructionKey.CreateSubKey(instructionString);

                // Increase the Count value.
                IncrementCounter(instructionKey);
            }
            finally
            {
                if (deleteKey != null)
                    deleteKey.Close();
                if (instructionKey != null)
                    instructionKey.Close();
                if (userSettingsKey != null)
                    userSettingsKey.Close();
            }
        }

        #endregion

    }
}
